package wortubung.lang.es;

import static wortubung.util.CommonUtils.*;

import wortubung.util.ImmutableStringList;

public class ConjugadorUtil {

	static final ImmutableStringList FUTURO_INDICES      = isl("é",  "ás",  "á",  "emos",  "éis",  "án" );
	static final ImmutableStringList CONDICIONAL_INDICES = isl("ía", "ías", "ía", "íamos", "íais", "ían");

	// -ar, -er, -ir; same below.
	static final ImmutableStringList[] PRESENTE_INDICES = {
		isl("o", "as", "a", "amos", "áis", "an"), // also -arse, e.g., lavarse, sentarse
		isl("o", "es", "e", "emos", "éis", "en"),
		isl("o", "es", "e", "imos", "ís",  "en"),
	};

    static final ImmutableStringList[] IMPERATIVE_INDICES = {
    	isl(null, "a", "e", "emos", "ad", "en"),
    	isl(null, "e", "a", "amos", "ed", "an"),
    	isl(null, "e", "a", "amos", "id", "an"),
    };

	static final ImmutableStringList[] PRETERITO_SIMPLE_INDICES = {
		isl("é", "aste", "ó",  "amos", "asteis", "aron" ),
		isl("í", "iste", "ió", "imos", "isteis", "ieron"),
		null,
	};

	static final ImmutableStringList[] PRETERITO_IMPERFECTO_INDICES = {
		isl("aba", "abas", "aba", "ábamos", "abais", "aban"),
		isl("ía",  "ías",  "ía",  "íamos",  "íais",  "ían" ),
		null,
	};

	static final ImmutableStringList[] SUBJUNCTIVO_PRESENTE_INDICES = {
		isl("e", "es", "e", "emos", "éis", "en"),
		isl("a", "as", "a", "amos", "áis", "an"),
		null,
	};

	static final ImmutableStringList[] SUBJUNCTIVO_PRETERITO_IMPERFECTO_INDICES = {
		isl("ara",  "aras",  "ara",  "áramos",  "arais",  "aran"),
		isl("iera", "ieras", "iera", "iéramos", "ierais", "ieran"),
		null,
	};

	static {
		PRETERITO_SIMPLE_INDICES[2] = PRETERITO_SIMPLE_INDICES[1];
		PRETERITO_IMPERFECTO_INDICES[2] = PRETERITO_IMPERFECTO_INDICES[1];
		SUBJUNCTIVO_PRESENTE_INDICES[2] = SUBJUNCTIVO_PRESENTE_INDICES[1];
		SUBJUNCTIVO_PRETERITO_IMPERFECTO_INDICES[2] = SUBJUNCTIVO_PRETERITO_IMPERFECTO_INDICES[1];
	}

	// Verb endings
	static final int AR = 0;
	static final int ER = 1;
	static final int IR = 2;

	static String[] appendToRoot(String root, int verbEnding, ImmutableStringList suffices) {
		String [] result = new String[suffices.size()];
		for (int i=0; i<suffices.size(); ++i) {
			String suffix = suffices.get(i);
			if (suffix == null)
				result[i] = null;
			else if (isEmpty(suffix))
				result[i] = root;
			else
				result[i] = phonetique(root, verbEnding, suffices.get(i));
		}
		return result;
	}

	/**
	 * 1. c  [AR] + e/é -> qu  -- e.g. buscar
	 * 2. g  [AR] + e/é -> gu  -- e.g. cargar
	 * 3. gu [AR] + e/é -> gü  -- e.g. averiguar
	 * 4. z  [AR] + e/é -> c   -- e.g. realizar
	 * 
	 * 5. g  [ER] + a/o -> j   -- e.g. coger
	 * 
	 * 6. c  [IR] + a/o -> z   -- e.g. esparcir
	 * 7. qu [IR] + a/o -> c   -- e.g. delinquir
	 * 8. gu [IR] + a/o -> g   -- e.g. distinguir
	 */
	static String phonetique(String root, int verbEnding, String suffix) {
		char last = root.charAt(root.length()-1);
		switch(verbEnding) {
		case AR:
			if (last == 'c' && startsWithE(suffix)) // -- 1.
				return substituteAndSuffix(root, 1, "qu", suffix);
			if (last == 'g' && startsWithE(suffix)) // -- 2.
				return substituteAndSuffix(root, 1, "gu", suffix);
			if (last == 'z' && startsWithE(suffix)) // -- 4.
				return substituteAndSuffix(root, 1, "c", suffix);
			if (last == 'u' && root.endsWith("gu") && startsWithE(suffix)) // -- 3.
				return substituteAndSuffix(root, 1, "ü", suffix);
			break;
		case ER:
			if (last == 'g' && startsWithAO(suffix)) // -- 5.
				return substituteAndSuffix(root, 1, "j", suffix);
			break;
		case IR:
			if (!startsWithAO(suffix))
				break;
			if (last == 'c') // -- 6.
				return substituteAndSuffix(root, 1, "z", suffix);
			if (last == 'u') {
				if (root.endsWith("qu")) // -- 7.
					return substituteAndSuffix(root, 2, "c", suffix);
				if (root.endsWith("gu")) // -- 8.
					return substituteAndSuffix(root, 1, "", suffix);
			}
			break;
		}
		return root + suffix;
	}

	private static String substituteAndSuffix(String root, int endingLen, String replacement, String suffix) {
		return chopRight(root, endingLen) + replacement + suffix;
	}

	static boolean startsWithE(String suffix) {
		char ch = suffix.charAt(0);
		return (ch == 'e' || ch == 'é');
	}

	static boolean startsWithAO(String suffix) {
		char ch = suffix.charAt(0);
		return "aáoó".indexOf(ch) >= 0;
	}
}
